#include "playerVideo.h"
#include "ui_playerVideo.h"
#include "AppConfig.h"
#include<QFileDialog>
#include <QMessageBox>
#include <QList>

Q_DECLARE_METATYPE(VideoPlayerState)
PlayerVideo::PlayerVideo(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::PlayerVideo)
{
    ui->setupUi(this);
    FunctionTransfer::init(QThread::currentThreadId());
    //因为VideoPlayer::PlayerState是自定义的类型 要跨线程传递需要先注册一下
    qRegisterMetaType<VideoPlayerState>();
    ui->widget_container->installEventFilter(this);
    AppConfig::InitAllDataPath(); //初始化一些变量和路径信息
    AppConfig::loadConfigInfoFromFile();

    AppConfig::WriteLog(QString( "\n #############\n Version = %1 \n ##############").arg(AppConfig::VERSION_NAME));
    ///初始化播放器
    VideoPlayer::initPlayer();

    mPlayer = new VideoPlayer();
    mPlayer->setVideoPlayerCallBack(this);
//    mVolume = mPlayer->getVolume();
    mPlayer->setVolume(mVolume/100);
    ui->horizontalSlider_volume->setValue(mVolume);
    mTimer = new QTimer; //定时器-获取当前视频时间
    connect(mTimer, &QTimer::timeout, this, &PlayerVideo::slotTimerTimeOut);
    mTimer->setInterval(500);

    ui->pushButton_pause->hide();

   connect(ui->pushButton_open, &QPushButton::clicked, this, &PlayerVideo::slotBtnClick);
   connect(ui->toolButton_open, &QPushButton::clicked, this, &PlayerVideo::slotBtnClick);
   connect(ui->pushButton_play, &QPushButton::clicked, this, &PlayerVideo::slotBtnClick);
   connect(ui->pushButton_pause,&QPushButton::clicked, this, &PlayerVideo::slotBtnClick);
   connect(ui->pushButton_stop, &QPushButton::clicked, this, &PlayerVideo::slotBtnClick);
   connect(ui->pushButton_volume, &QPushButton::clicked, this, &PlayerVideo::slotBtnClick);
    ui->horizontalLayout_4->setAlignment(Qt::AlignCenter);
    ui->label_totaltime->setAlignment(Qt::AlignRight);
    ui->label_2->setAlignment(Qt::AlignRight);
    ui->label_currenttime->setAlignment(Qt::AlignRight);
   ui->horizontalLayout_4->setStretch(0, 70);
   ui->horizontalLayout_4->setStretch(1, 15);
    ui->horizontalLayout_4->setStretch(2, 1);
    ui->horizontalLayout_4->setStretch(3, 15);

   connect(ui->horizontalSlider, SIGNAL(sig_valueChanged(int)), this, SLOT(slotSliderMoved(int)));
   connect(ui->horizontalSlider_volume, SIGNAL(valueChanged(int)), this, SLOT(slotSliderMoved(int)));


   connect(ui->stackedWidget,SIGNAL(currentChanged(int)),this,SLOT(stackCurrentChanged(int)));
     ui->stackedWidget->setCurrentWidget(ui->page_open);
//     ui->gridLayoutWidget->setMaximumSize(100,100);
     ui->gridLayoutWidget->setMaximumHeight(110);
     ui->gridLayout->setColumnMinimumWidth(0,20);
     ui->gridLayout->setColumnMinimumWidth(1,100);
    QList<QLabel *> gLabels=   ui->gridLayoutWidget->findChildren<QLabel *>();
     foreach (QLabel *button, gLabels) {
         button->setStyleSheet("color: red");

     }

}
void PlayerVideo::stackCurrentChanged(int currentPage){
    qDebug()<<currentPage;
    if(currentPage==2){
        ui->gridLayoutWidget->show();
    }else{
        ui->gridLayoutWidget->hide();
    }
}
void PlayerVideo::slotBtnClick(bool isChecked){
    if (QObject::sender() == ui->pushButton_play)
    {
       mPlayer->play();
    }
    else if (QObject::sender() == ui->pushButton_pause)
    {
       mPlayer->pause();
    }
    else if (QObject::sender() == ui->pushButton_stop)
    {
      mPlayer->stop(true);
    }
    else if (QObject::sender() == ui->pushButton_open || QObject::sender() == ui->toolButton_open)
    {
        QString s = QFileDialog::getOpenFileName(
                   this, QStringLiteral("选择要播放的文件"),
                    AppConfig::gVideoFilePath,//初始目录
                    QStringLiteral("视频文件 (*.flv *.rmvb *.avi *.MP4 *.mkv *.mov);;")
                    +QStringLiteral("音频文件 (*.mp3 *.wma *.wav);;")
                    +QStringLiteral("所有文件 (*.*)"));
        if (!s.isEmpty())
        {
            mPlayer->stop(true); //如果在播放则先停止
            qDebug()<<s;
            qDebug()<<s.toStdString().c_str();

            std::string path=s.toStdString();
            mPlayer->startPlay(path);

            AppConfig::gVideoFilePath = s;
            AppConfig::saveConfigInfoToFile();
        }
    }
    else if (QObject::sender() == ui->pushButton_volume)
    {
       qDebug()<<isChecked;

        bool isMute = isChecked;
        mPlayer->setMute(isMute);

        if (isMute)
        {
            ui->horizontalSlider_volume->setValue(0);
            ui->horizontalSlider_volume->setEnabled(false);
            ui->label_volume->setText(QString("%1").arg(0));
        }
        else
        {
            int volume = mVolume * 100.0;
            ui->horizontalSlider_volume->setValue(volume);
            ui->horizontalSlider_volume->setEnabled(true);
            ui->label_volume->setText(QString("%1").arg(volume));
        }

    }

}

PlayerVideo::~PlayerVideo()
{
    AppConfig::saveConfigInfoToFile();
    AppConfig::removeDirectory(AppConfig::AppDataPath_Tmp);
    delete ui;
}



//图片显示部件时间过滤器处理
bool PlayerVideo::eventFilter(QObject *target, QEvent *event)
{
    if(target == ui->widget_container)
    {
        if(event->type() == QEvent::Resize)
        {
            QResizeEvent * e = (QResizeEvent*)event;
            int w = e->size().width();
            int h = e->size().height();
            ui->stackedWidget->move(0, 0);
            int x = 0;
            int y = h - ui->widget_controller->height();
            ui->stackedWidget->resize(w, y);

            int gridX = w-120;
            ui->gridLayoutWidget->move(gridX,10);
            ui->gridLayoutWidget->resize(ui->gridLayoutWidget->width(),ui->gridLayoutWidget->height());
            ui->widget_controller->move(x, y);
            ui->widget_controller->resize(w, ui->widget_controller->height());

        }
    }

    return true;
}


void PlayerVideo::slotTimerTimeOut(){
    if (QObject::sender() == mTimer)
    {
        qint64 Sec = mPlayer->getCurrentTime();

        ui->horizontalSlider->setValue(Sec);

        QString curTime;
        QString hStr = QString("0%1").arg(Sec / 3600);
        QString mStr = QString("0%1").arg(Sec / 60 % 60);
        QString sStr = QString("0%1").arg(Sec % 60);
        if (hStr == "00")
        {
            curTime = QString("%1:%2").arg(mStr.right(2)).arg(sStr.right(2));
        }
        else
        {
            curTime = QString("%1:%2:%3").arg(hStr).arg(mStr.right(2)).arg(sStr.right(2));
        }

        ui->label_currenttime->setText(curTime);
    }

}
void PlayerVideo::slotSliderMoved(int value)
{
    if (QObject::sender() == ui->horizontalSlider)
    {
        mPlayer->seek((qint64)value * 1000000);
    }
    else if (QObject::sender() == ui->horizontalSlider_volume)
    {
         qDebug()<<"声音大小："<<value;
        mPlayer->setVolume(value / 100.0);
        ui->label_volume->setText(QString("%1").arg(value));
    }
}

///打开文件失败
void PlayerVideo::onOpenVideoFileFailed(const int &code)
{
    FunctionTransfer::runInMainThread([=]()
    {
        QMessageBox::critical(NULL, "tips", QString("open file failed %1").arg(code));
    });
}

///打开SDL失败的时候回调此函数
void PlayerVideo::onOpenSdlFailed(const int &code)
{
    FunctionTransfer::runInMainThread([=]()
    {
        QMessageBox::critical(NULL, "tips", QString("open Sdl failed %1").arg(code));
    });
}

///获取到视频时长的时候调用此函数
void PlayerVideo::onTotalTimeChanged(const VideoInfo &videoInfo1)
{
    FunctionTransfer::runInMainThread([=]()
    {
        int64_t uSec = videoInfo1.duration;
        int64_t rate=  videoInfo1.rate;
        qDebug()<<"比特率："<<QString::number(rate);
        ui->label_rate_v->setText(QString::number(rate).append(" kb/s"));
       int fps= videoInfo1.fps;
       ui->label_fps_v->setText(QString::number(fps).append(" fps"));
       int width = videoInfo1.width;
       int height=videoInfo1.height;
       ui->label_width_v->setText(QString::number(width));
        ui->label_height_v->setText(QString::number(height));
        videoInfo = videoInfo1;
        videoInfo.isFill=true;
        qint64 Sec = uSec/1000000;

        ui->horizontalSlider->setRange(0,Sec);

        QString totalTime;
        QString hStr = QString("0%1").arg(Sec/3600);
        QString mStr = QString("0%1").arg(Sec / 60 % 60);
        QString sStr = QString("0%1").arg(Sec % 60);
        if (hStr == "00")
        {
            totalTime = QString("%1:%2").arg(mStr.right(2)).arg(sStr.right(2));
        }
        else
        {
            totalTime = QString("%1:%2:%3").arg(hStr).arg(mStr.right(2)).arg(sStr.right(2));
        }

        ui->label_totaltime->setText(totalTime);
    });
}

///播放器状态改变的时候回调此函数
void PlayerVideo::onPlayerStateChanged(const VideoPlayerState &state, const bool &hasVideo, const bool &hasAudio)
{
    FunctionTransfer::runInMainThread([=]()
    {
        if (state == VideoPlayer_Stop)
        {
            ui->stackedWidget->setCurrentWidget(ui->page_open);

            ui->pushButton_pause->hide();
            ui->widget_videoPlayer->clear();

            ui->horizontalSlider->setValue(0);
            ui->label_currenttime->setText("00:00");
            ui->label_totaltime->setText("00:00");

            mTimer->stop();

        }
        else if (state == VideoPlayer_Playing)
        {
            if (hasVideo)
            {
                ui->stackedWidget->setCurrentWidget(ui->page_video);
            }
            else
            {
                ui->stackedWidget->setCurrentWidget(ui->page_audio);
            }

            ui->pushButton_play->hide();
            ui->pushButton_pause->show();

            mTimer->start();
        }
        else if (state == VideoPlayer_Pause)
        {
            if (hasVideo)
            {
                ui->stackedWidget->setCurrentWidget(ui->page_video);
            }
            else
            {
                ui->stackedWidget->setCurrentWidget(ui->page_audio);
            }

            ui->pushButton_pause->hide();
            ui->pushButton_play->show();
        }
    });
}

///显示视频数据，此函数不宜做耗时操作，否则会影响播放的流畅性。
void PlayerVideo::onDisplayVideo(std::shared_ptr<VideoFrame> videoFrame)
{
    ui->widget_videoPlayer->inputOneFrame(videoFrame);
}

QString PlayerVideo::getFilePath(){
    qDebug()<< AppConfig::gVideoFilePath;
    return   AppConfig::gVideoFilePath;
}
VideoInfo PlayerVideo::getVideoInfo(){
    return videoInfo;
}
